home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_10 / vesely / trycatch.cpp < prev   
Text File  |  1995-08-02  |  3KB  |  89 lines

  1. // Vesely::MFC-TRY/CATCH : listing 2
  2.  
  3. // replacement for AfxThrow
  4. void AFXAPI CppThrow(CException* pException, BOOL bShared);
  5.  
  6. class CExceptionMonitor
  7. {
  8. public:
  9.    typedef void(*Callback)( BOOL bStartUnwinding);
  10.  
  11. private:
  12.    static int m_nCount;
  13.    static Callback m_pfCallback;
  14.  
  15.    BOOL m_bResumed;
  16.  
  17.    friend void AFXAPI CppThrow(CException* pException,
  18.       BOOL bShared);      // calls here
  19.    static void OnThrow(); // just before each throw
  20.  
  21. public:
  22.    CExceptionMonitor() : m_bResumed( FALSE)
  23.    {
  24.       // there must be one auto object inside each handler's block,
  25.       // as done in the macro redefinitions below
  26.       ASSERT( m_nCount > 0);
  27.    }
  28.  
  29.    ~CExceptionMonitor();
  30.    void Resume();
  31.    static BOOL Unwinding() { ASSERT( m_nCount >= 0); return m_nCount; }
  32.    static Callback HookOnThrow( Callback newCallback);
  33. };
  34.  
  35. #if defined( _DEBUG)
  36. class CDebugException : public CException
  37. // only CATCH_ALL/END_CATCH_ALL get this:
  38. // CATCH( CDebugException, e) => compile error in retail build
  39. {
  40.    DECLARE_DYNAMIC( CDebugException)
  41. public:
  42.    CDebugException();
  43. };
  44.  
  45. // this intermittently throws the relevant exception
  46. void ThrowPointTest( CRuntimeClass *pE, LPCSTR lpszFileName, int nLine);
  47.  
  48. #define EXCEPTIONS_CAN_BE_THROWN(e) \
  49.    ThrowPointTest( RUNTIME_CLASS( e), THIS_FILE, __LINE__)
  50. #else
  51. #define EXCEPTIONS_CAN_BE_THROWN(e) ((void)0)
  52. #endif // _DEBUG
  53.  
  54. #undef TRY
  55. #define TRY { AFX_EXCEPTION_LINK_ _afxExceptionLink; \
  56.    try { EXCEPTIONS_CAN_BE_THROWN( CDebugException); {
  57.  
  58. #undef CATCH
  59. // CATCH can only be the first handler in the list:
  60. // in the (rare) case of a handler list with more than one
  61. // meaningful selective handler, EXCEPTIONS_CAN_BE_THROWN
  62. // needs to be coded explicitely.
  63. #define CATCH(class, e) EXCEPTIONS_CAN_BE_THROWN( class); } \
  64.         } catch (class* e) \
  65.         { ASSERT( e->IsKindOf(RUNTIME_CLASS(class))); \
  66.           ASSERT( _afxExceptionLink.m_pException == e); \
  67.           CExceptionMonitor ExceptionMonitor;
  68.  
  69. #undef AND_CATCH
  70. #define AND_CATCH(class, e) } catch (class* e) \
  71.         { ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \
  72.           ASSERT( _afxExceptionLink.m_pException == e); \
  73.           CExceptionMonitor ExceptionMonitor;
  74.  
  75. #undef END_CATCH
  76. #define END_CATCH } catch (CException* e) \
  77.         { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
  78.           ASSERT( _afxExceptionLink.m_pException == e); \
  79.           CExceptionMonitor ExceptionMonitor; \
  80.           CppThrow( 0, FALSE); } }
  81.  
  82. #undef THROW
  83. #define THROW(e) CppThrow( e, FALSE)
  84.  
  85. #undef THROW_LAST
  86. #define THROW_LAST() CppThrow( 0, FALSE)
  87. // end of listing 2
  88. 
  89.